package org.sunyaxing.transflow.transflowapp.plugins.outs;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.gitlab4j.api.GitLabApi;
import org.gitlab4j.api.models.Note;
import org.gitlab4j.api.models.Position;
import org.sunyaxing.transflow.api.TransData;
import org.sunyaxing.transflow.api.common.Handle;
import org.sunyaxing.transflow.api.common.ano.Extension;
import org.sunyaxing.transflow.api.common.ano.JobParamItem;
import org.sunyaxing.transflow.api.common.ano.ScopeContentCheck;
import org.sunyaxing.transflow.api.extensions.base.ExtensionContext;
import org.sunyaxing.transflow.api.extensions.base.typesimpl.TransFlowOutputWithHandler;
import org.sunyaxing.transflow.transflowapp.controllers.JobLogsWs;

import java.util.List;
import java.util.function.Function;

@Extension("plugin-gitlab-ai-codeview-outer")
@ScopeContentCheck(
        value = {
                @JobParamItem(field = "gitHost", label = "gitHost"),
                @JobParamItem(field = "gitToken", type = "password", label = "gitToken"),
        }
)
public class GitlabAiReviewCodeOutputExt extends TransFlowOutputWithHandler<String, String> {
    private static final Logger log = LogManager.getLogger(GitlabAiReviewCodeOutputExt.class);
    private GitLabApi gitLabApi;

    public GitlabAiReviewCodeOutputExt(ExtensionContext extensionContext) {
        super(extensionContext);
    }

    @Override
    protected void batchExec(List<String> dataList) {

    }

    @Override
    protected void afterInitHandler(JSONObject config, List<Handle> handles) {
        final String gitHost = config.getString("gitHost");
        final String gitToken = config.getString("gitToken");
        this.gitLabApi = new GitLabApi(gitHost, gitToken);
        this.gitLabApi.setIgnoreCertificateErrors(true);
        this.gitLabApi.enableRequestResponseLogging();
    }

    @Override
    public Function<TransData<String>, String> parseHandleToConsumer(String handleId, String handleValue) {
        return transData -> {
            String transDataStr = transData.getData();
            GitLabNoteMsg gitLabNoteMsg = JSONObject.parseObject(transDataStr, GitLabNoteMsg.class);
            if (!gitLabNoteMsg.valid()) {
                JobLogsWs.sendMessage(jobId, "【{}】【P[{}] R[{}]】 评论数据非法 ...",extensionContext.getNodeName(), gitLabNoteMsg.getPid(), gitLabNoteMsg.getMrId());
                return transData.getData();
            }
            Long projectId = gitLabNoteMsg.getPid();
            Long mergeRequestIid = gitLabNoteMsg.getMrId();
            String contentStr = gitLabNoteMsg.getContentStr();
            if (contentStr.contains("SKIP_CODE")) {
                JobLogsWs.sendMessage(jobId, "【{}】【P[{}] R[{}]】 代码无异常跳过评论",extensionContext.getNodeName(), projectId, mergeRequestIid);
            } else {
                try {
                    JobLogsWs.sendMessage(jobId, "【{}】【P[{}] R[{}]】 添加代码评论",extensionContext.getNodeName(), projectId, mergeRequestIid);
                    gitLabApi.getNotesApi().createMergeRequestNote(
                            projectId,
                            mergeRequestIid,
                            contentStr
                    );
                } catch (Exception e) {
                    JobLogsWs.sendMessage(jobId, "【{}】【P[{}] R[{}]】 评论失败 ...",extensionContext.getNodeName(), projectId, mergeRequestIid);
                }
            }
            return transData.getData();
        };
    }

    @Data
    public static class GitLabNoteMsg {
        private Long pid;
        private Long mrId;
        private String userMsg;
        private String contentStr;

        public boolean valid() {
            try {
                Assert.notNull(pid, "pid is null");
                Assert.notNull(mrId, "mrId is null");
            } catch (IllegalArgumentException e) {
                return false;
            }
            return true;
        }
    }

    @Override
    public void destroy() {
        super.destroy();
        this.gitLabApi.close();
    }
}
